const iterable = {
  arr: ['one', 'two', 'three'],
  current: 0,
  next() {
    if (this.current === this.arr.length) {
      return {
        done: true,
      }
    }
    return {
      done: false,
      value: this.arr[this.current++],
    }
  },
  [Symbol.iterator]: function () {
    this.current = 0;
    return this;
  }
}
console.log('+++++++++++++++');
for (item of iterable) {
  console.log(item);
  // console.log(';\r\n');
}
console.log('+++++++++++++++');


console.log('----------');
const str = new String('abc');
strIterable = str[Symbol.iterator]();
console.log(strIterable.next().value);
console.log(strIterable.next().value);
console.log(strIterable.next().value);
console.log(strIterable.next().value);
console.log('----------');

console.log('+++++++++++++++');
const str2 = new String('hi');
str2[Symbol.iterator] = function () {
  return {
    next() {
      if (this.first) {
        this.first = false;
        return {
          done: false,
          value: 'bye',
        }
      }
      return {
        done: true,
      }
    },
    first: true,
  }
}

console.log([...str2]);
console.log('+++++++++++++++');

console.log('----------');
const gen = {};
gen[Symbol.iterator] = function *() {
  yield 1;
  yield 2;
  yield 3;
}

console.log([...gen]);

console.log('----------');

console.log('+++++++++++++++');
let aGeneratorObject = function* (){
  yield 1;
  yield 2;
  yield 3;
}();

console.log(typeof aGeneratorObject.next);
// 返回"function", 因为有一个next方法，所以这是一个迭代器

console.log(typeof aGeneratorObject[Symbol.iterator]);
// 返回"function", 因为有一个@@iterator方法，所以这是一个可迭代对象

console.log(aGeneratorObject[Symbol.iterator]() === aGeneratorObject);
// 返回true, 因为@@iterator方法返回自身（即迭代器），所以这是一个格式良好的可迭代对象

console.log([...aGeneratorObject]);
// 返回[1, 2, 3]

console.log(Symbol.iterator in aGeneratorObject)
// 返回true, 因为@@iterator方法是aGeneratorObject的一个属性


console.log('+++++++++++++++');